using MediatR;
using ProduceBasicData.Api.Application.Command.OutboundOrder;
using ProduceBasicData.Api.DTO;
using ProduceBasicData.Domain.WarehouseManage;
using ProduceBasicData.ErrorCode;
using ProduceBasicData.Infrastructure.Interface;

namespace ProduceBasicData.Api.Application.Handler.OutboundOrder
{
    /// <summary>
    /// 获取出货订单数据处理类
    /// </summary>
    public class GetOutboundOrderDataHandler : IRequestHandler<GetOutboundOrderDataCommand, ApiResult<OutboundOrderChartDto>>
    {
        private readonly IBaseRespository<StockOutOrder> _stockOutOrderRepository;
        private readonly IBaseRespository<StockOutOrderItem> _stockOutOrderItemRepository;

        public GetOutboundOrderDataHandler(
            IBaseRespository<StockOutOrder> stockOutOrderRepository,
            IBaseRespository<StockOutOrderItem> stockOutOrderItemRepository)
        {
            _stockOutOrderRepository = stockOutOrderRepository;
            _stockOutOrderItemRepository = stockOutOrderItemRepository;
        }

        public async Task<ApiResult<OutboundOrderChartDto>> Handle(GetOutboundOrderDataCommand request, CancellationToken cancellationToken)
        {
            ApiResult<OutboundOrderChartDto> result = new ApiResult<OutboundOrderChartDto>();

            try
            {
                var chartData = new OutboundOrderChartDto();

                // 计算时间范围
                var (currentStartDate, currentEndDate, lastYearStartDate, lastYearEndDate) = CalculateDateRange(request.TimePeriodType, request.StartDate, request.EndDate);

                // 获取当前期间的出货订单数据
                var currentPeriodData = await GetOrderDataByPeriod(currentStartDate, currentEndDate, request);

                // 获取去年同期的出货订单数据
                var lastYearPeriodData = await GetOrderDataByPeriod(lastYearStartDate, lastYearEndDate, request);

                // 构建出货订单数据
                var orderDataList = BuildOrderDataList(currentPeriodData, lastYearPeriodData, request.OnlyWithOrders);

                // 应用排序
                orderDataList = ApplySorting(orderDataList, request.SortType);

                // 应用分页
                if (request.PageSize > 0)
                {
                    orderDataList = orderDataList.Take(request.PageSize).ToList();
                }

                chartData.OrderData = orderDataList;

                // 计算统计信息
                chartData.Statistics = CalculateStatistics(orderDataList);

                // 构建图表数据
                if (request.IncludeChartData)
                {
                    chartData.ChartData = BuildChartData(orderDataList);
                }

                result.Code = ApiEnum.Success;
                result.Msg = "查询成功";
                result.Data = chartData;
            }
            catch (Exception ex)
            {
                result.Code = ApiEnum.Failed;
                result.Msg = $"查询失败：{ex.Message}";
                result.Data = new OutboundOrderChartDto();
            }

            return result;
        }

        /// <summary>
        /// 计算时间范围
        /// </summary>
        private (DateTime currentStart, DateTime currentEnd, DateTime lastYearStart, DateTime lastYearEnd) CalculateDateRange(int timePeriodType, DateTime? startDate, DateTime? endDate)
        {
            DateTime currentStart, currentEnd, lastYearStart, lastYearEnd;

            switch (timePeriodType)
            {
                case 1: // 上月
                    currentStart = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMonths(-1);
                    currentEnd = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddDays(-1);
                    lastYearStart = currentStart.AddYears(-1);
                    lastYearEnd = currentEnd.AddYears(-1);
                    break;
                case 2: // 本月
                    currentStart = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                    currentEnd = DateTime.Now;
                    lastYearStart = currentStart.AddYears(-1);
                    lastYearEnd = currentEnd.AddYears(-1);
                    break;
                case 3: // 近6个月
                    currentStart = DateTime.Now.AddMonths(-6);
                    currentEnd = DateTime.Now;
                    lastYearStart = currentStart.AddYears(-1);
                    lastYearEnd = currentEnd.AddYears(-1);
                    break;
                case 4: // 自定义
                    currentStart = startDate ?? DateTime.Now.AddMonths(-1);
                    currentEnd = endDate ?? DateTime.Now;
                    lastYearStart = currentStart.AddYears(-1);
                    lastYearEnd = currentEnd.AddYears(-1);
                    break;
                default:
                    currentStart = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                    currentEnd = DateTime.Now;
                    lastYearStart = currentStart.AddYears(-1);
                    lastYearEnd = currentEnd.AddYears(-1);
                    break;
            }

            return (currentStart, currentEnd, lastYearStart, lastYearEnd);
        }

        /// <summary>
        /// 获取指定期间的订单数据
        /// </summary>
        private async Task<Dictionary<int, (string CustomerName, int OrderQuantity)>> GetOrderDataByPeriod(DateTime startDate, DateTime endDate, GetOutboundOrderDataCommand request)
        {
            var stockOutOrders = _stockOutOrderRepository.GetAll()
                .Where(x => !x.Isdel && 
                           x.ActualOutDate.HasValue &&
                           x.ActualOutDate.Value >= startDate && 
                           x.ActualOutDate.Value <= endDate);

            // 应用筛选条件
            if (request.CustomerId.HasValue)
            {
                stockOutOrders = stockOutOrders.Where(x => x.CustomerId == request.CustomerId.Value);
            }

            if (request.OutType.HasValue)
            {
                stockOutOrders = stockOutOrders.Where(x => (int)x.OutType == request.OutType.Value);
            }

            if (request.Status.HasValue)
            {
                stockOutOrders = stockOutOrders.Where(x => (int)x.Status == request.Status.Value);
            }

            var orderData = new Dictionary<int, (string CustomerName, int OrderQuantity)>();

            // 按客户分组统计订单数量
            var customerGroups = stockOutOrders
                .Where(x => x.CustomerId.HasValue && !string.IsNullOrEmpty(x.CustomerName))
                .GroupBy(x => x.CustomerId.Value)
                .ToList();

            foreach (var group in customerGroups)
            {
                var customerId = group.Key;
                var customerName = group.First().CustomerName ?? "";
                var orderQuantity = group.Count();

                orderData[customerId] = (customerName, orderQuantity);
            }

            return await Task.FromResult(orderData);
        }


        /// <summary>
        /// 构建订单数据列表
        /// </summary>
        private List<OutboundOrderDataDto> BuildOrderDataList(
            Dictionary<int, (string CustomerName, int OrderQuantity)> currentData,
            Dictionary<int, (string CustomerName, int OrderQuantity)> lastYearData,
            bool onlyWithOrders)
        {
            var orderDataList = new List<OutboundOrderDataDto>();
            int serialNumber = 1;

            // 获取所有客户ID
            var allCustomerIds = currentData.Keys.Union(lastYearData.Keys).Distinct().ToList();

            foreach (var customerId in allCustomerIds)
            {
                var currentInfo = currentData.ContainsKey(customerId) ? currentData[customerId] : ("", 0);
                var lastYearInfo = lastYearData.ContainsKey(customerId) ? lastYearData[customerId] : ("", 0);

                // 如果只显示有订单的客户，且当前期间和去年同期都没有订单，则跳过
                if (onlyWithOrders && currentInfo.Item2 == 0 && lastYearInfo.Item2 == 0)
                {
                    continue;
                }

                var customerName = !string.IsNullOrEmpty(currentInfo.Item1) ? currentInfo.Item1 : lastYearInfo.Item1;

                // 计算同比变化
                var yearOverYearChange = CalculateYearOverYearChange(currentInfo.Item2, lastYearInfo.Item2);

                var orderData = new OutboundOrderDataDto
                {
                    SerialNumber = serialNumber++,
                    CustomerName = customerName,
                    YearOverYearChange = yearOverYearChange,
                    YearOverYearDisplay = FormatYearOverYearDisplay(yearOverYearChange),
                    YearOverYearColor = GetYearOverYearColor(yearOverYearChange),
                    OrderQuantity = currentInfo.Item2,
                    CustomerId = customerId,
                    CurrentPeriodQuantity = currentInfo.Item2,
                    LastYearPeriodQuantity = lastYearInfo.Item2
                };

                orderDataList.Add(orderData);
            }

            return orderDataList;
        }

        /// <summary>
        /// 计算同比变化
        /// </summary>
        private decimal CalculateYearOverYearChange(int currentQuantity, int lastYearQuantity)
        {
            if (lastYearQuantity == 0)
            {
                return currentQuantity > 0 ? 100 : 0;
            }

            return Math.Round((decimal)(currentQuantity - lastYearQuantity) / lastYearQuantity * 100, 2);
        }

        /// <summary>
        /// 格式化同比变化显示
        /// </summary>
        private string FormatYearOverYearDisplay(decimal change)
        {
            if (change > 0)
            {
                return $"↑{change:F1}%";
            }
            else if (change < 0)
            {
                return $"↓{Math.Abs(change):F1}%";
            }
            else
            {
                return "↓0%";
            }
        }

        /// <summary>
        /// 获取同比变化颜色
        /// </summary>
        private string GetYearOverYearColor(decimal change)
        {
            if (change > 0)
            {
                return "#67C23A"; // 绿色
            }
            else if (change < 0)
            {
                return "#F56C6C"; // 红色
            }
            else
            {
                return "#F56C6C"; // 红色（无变化也显示为红色）
            }
        }

        /// <summary>
        /// 应用排序
        /// </summary>
        private List<OutboundOrderDataDto> ApplySorting(List<OutboundOrderDataDto> orderDataList, int sortType)
        {
            return sortType switch
            {
                1 => orderDataList.OrderBy(x => x.OrderQuantity).ToList(), // 按订单数量升序
                2 => orderDataList.OrderByDescending(x => x.OrderQuantity).ToList(), // 按订单数量降序
                3 => orderDataList.OrderBy(x => x.CustomerName).ToList(), // 按客户名称
                4 => orderDataList.OrderByDescending(x => x.YearOverYearChange).ToList(), // 按同比变化
                _ => orderDataList.OrderByDescending(x => x.OrderQuantity).ToList()
            };
        }

        /// <summary>
        /// 计算统计信息
        /// </summary>
        private OutboundOrderStatistics CalculateStatistics(List<OutboundOrderDataDto> orderDataList)
        {
            var statistics = new OutboundOrderStatistics
            {
                TotalCustomers = orderDataList.Count,
                TotalOrderQuantity = orderDataList.Sum(x => x.OrderQuantity),
                MaxOrderQuantity = orderDataList.Any() ? orderDataList.Max(x => x.OrderQuantity) : 0,
                MinOrderQuantity = orderDataList.Any() ? orderDataList.Min(x => x.OrderQuantity) : 0,
                GrowingCustomers = orderDataList.Count(x => x.YearOverYearChange > 0),
                DecliningCustomers = orderDataList.Count(x => x.YearOverYearChange < 0),
                UnchangedCustomers = orderDataList.Count(x => x.YearOverYearChange == 0)
            };

            statistics.AverageOrderQuantity = statistics.TotalCustomers > 0 
                ? Math.Round((decimal)statistics.TotalOrderQuantity / statistics.TotalCustomers, 2)
                : 0;

            return statistics;
        }

        /// <summary>
        /// 构建图表数据
        /// </summary>
        private OutboundOrderChartData BuildChartData(List<OutboundOrderDataDto> orderDataList)
        {
            return new OutboundOrderChartData
            {
                CustomerNames = orderDataList.Select(x => x.CustomerName).ToList(),
                OrderQuantities = orderDataList.Select(x => x.OrderQuantity).ToList(),
                YearOverYearChanges = orderDataList.Select(x => x.YearOverYearChange).ToList(),
                YearOverYearColors = orderDataList.Select(x => x.YearOverYearColor).ToList()
            };
        }
    }
}
